实践
创建一个简单的计算器, 当用户输入整数时, 输出其平方值. 但用户需要登录才能进行操作, 用户的登录信息放在web.xml中, 每次登录用户可以使用该计算器三次, 三次使用结束后, 提示用户推出后重新登录继续使用.
User Case 用例 |
登录系统 |
||
Brief description |
登录系统 |
||
Scope/Level |
AthenaES/User goal |
Primary actor/role |
Root |
Minimal & Success Guarantees 保证 |
Minimal: The system logs how far it may get |
||
Preconditions 前提 |
无 |
||
Triggers 引发条件 |
用户打开登录界面 |
||
Main Success Scenario 成功场景 |
1. 系统提示用户输入用户名及密码 |
||
Extension 扩展 #1 |
3a: 系统无法核实用户身份, 提示其用户名或密码错误, 并提示用户重新输入 |
||
Notes and Issues |
无 |
User Case 用例 |
计算平方 |
||
Brief description |
计算平方 |
||
Scope/Level |
AthenaES/User goal |
Primary actor/role |
Root |
Minimal & Success Guarantees 保证 |
Minimal: The system logs how far it may get |
||
Preconditions 前提 |
Actor is logged in |
||
Triggers 引发条件 |
用户点击”计算” |
||
Main Success Scenario 成功场景 |
1. 确认用户使用次数未达到上限 |
||
Extension 扩展 #1 |
1a: 用户使用次数达到上限, 系统提示用户重新登陆后继续使用 |
||
Extension 扩展 #2 |
4a: 系统检测到用户输入不合法, 系统提示用户重新输入 用户重新进行2~4 |
||
Notes and Issues |
无 |
1. ServltContext层次的数据: 由于用户名及最大限制次数等信息在整个Servlet进程中都会被使用, 因此使用Context的Listener来实现.
2. Session层次的数据: 用户本次登录已使用次数应记录在Seesion中, 在当前Session中使用
3. Request层次的数据: 用户输入的数值尽在当前Request中使用
Calc主页面实现: |
首先检查Session是否存在, 不存在则跳转到登录界面. |
package com.insprise.servletStu; //省略import public class Calc extends HttpServlet { public static final String MAX_CALCULATIONAS_PER_SESSION = “maxNumber”; // 最大使用次数的Key public static int MAX_CALCULATION_TIMES_PER_SESSION; // 最大使用次数 public static final String CURRENT_USER = “currentUser”; // 当前用户 public static final String URL_MAIN = “./Calc”; // 主页面 public static final String URL_LOGIN = “./Login”; // 登录页面 public static final String URL_LOGOUT = “./Logout”; // 注销页面 private static final String ACCESS_COUNT = “accessCount”; // 使用次数 private static final String INPUT_INT = “inputInt”; private static Logger log = Logger.getLogger(Calc.class); private static final int MAX_INT = 46340; // Math.sqrt(Integer.MAX_VALUE) private HttpSession session; private Integer accessCount; // 使用次数 public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { session = request.getSession(false); if (validatUser(session)) { // 已登录 accessCount = (Integer) session.getAttribute(ACCESS_COUNT); if (accessCount == null) { // 如果Session中不存在accessCount, 则表明其为新登录用户, // 赋值为0; accessCount = 0; session.setAttribute(ACCESS_COUNT, accessCount); } if (checkUseTimes(accessCount)) { // 已登录, 且使用次数在限制之内, 进行操作. proccessRequet(request, response); } else { // 已登录, 但使用次数操过限制,提示用户重新登陆. accessOverTime(request, response); } } else { // 未登录 response.sendRedirect(URL_LOGIN); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { doGet(request, response); } // 检查用户是否已登录 private boolean validatUser(HttpSession s) { if (session != null) { return true; } return false; } // 检查用户使用次数是否超过限制 private boolean checkUseTimes(Integer number) { //省略 } // 使用次数超过限制之后 提示其登录; private void accessOverTime(HttpServletRequest request, HttpServletResponse response) throws IOException { request.getSession().invalidate(); response.getWriter().println("本次登录已使用完毕, 请重新登录"); return; } // 获得输入数值, 计算结果, 返回信息 private void proccessRequet(HttpServletRequest request, HttpServletResponse response) throws IOException { Integer i; String title = "求整数平方"; response.setContentType("text/html"); response.setCharacterEncoding("utf-8"); // 不使用缓存 在点击推出后 按后退按钮时 不会出现缓存中的内容. response.setHeader("Cache-Control", "no-store"); response.setDateHeader("Expires", 0); response.setHeader("Pragma", "no-cache"); PrintWriter out = response.getWriter(); out.println(ServletUtilities.headwithTitle(title)); out.println("" + title + "
"); out.println("当前用户: " + session.getAttribute(CURRENT_USER) + " [退出]
"); String numberString = request.getParameter(INPUT_INT); if (numberString != null) { try { out.println("" + i + " 的平方是: " + calculator(i) + "
"); log.info("累计第[" + accessCount + "]次使用, 本次计算的参数为: " + i); } catch (Exception e) { out.println("您可能输入的不是整数 或您输入的整数绝对值过大请输入: 一个绝对值小于" + MAX_INT + " 的整数
"); } } out.println("您总共可以使用 " + MAX_CALCULATION_TIMES_PER_SESSION + "次, 您已累计使用:" + accessCount + "次
"); // 最后一次运行时, 停止输出Form; if (accessCount.equals(MAX_CALCULATION_TIMES_PER_SESSION)) { out.println("已达到最大使用次数限制, 请退出后重新登陆"); return; } printForm(out); out.println(""); } // 计算 private int calculator(int i) { accessCount = new Integer(accessCount.intValue() + 1); // 使用次数增加一次 session.setAttribute("accessCount", accessCount); return i * i; } // 打印一个Form private void printForm(PrintWriter out) { out.print("
// Proudly powered by Apache, PHP, MySQL, WordPress, Bootstrap, etc,.